<template>
  <view
    class="drawer"
    :class="`${show ? 'show' : 'hide'} placement-${placement} ${desc ? 'has-desc' : ''}`"
    :style="`--width: ${width};--height: ${height}`"
  >
    <view class="drawer-mask" :style="maskStyle" @click="closeDrawer"></view>
    <view class="drawer-inner" :style="modalWrapperStyles">
      <view class="drawer-header">
        <view class="header-title" :class="`align-${alignment}`">
          <text v-if="title">{{ title }}</text>
          <slot name="header"></slot>
        </view>

        <view class="close-btn" hover-class="hovering" @click="closeDrawer">
          <image class="close-icon" src="/static/Close.png" />
        </view>
      </view>
      <view class="drawer-body">
        <view v-if="desc || $slots.desc" class="drawer-desc">
          <text v-if="desc">{{ desc }}</text>
          <slot name="desc"></slot>
        </view>
        <slot></slot>
      </view>
      <view
        v-if="$slots.footer || type"
        class="drawer-footer"
        :class="{ bordered: footerBordered, 'is-button-group': type === 'confirm' }"
      >
        <block v-if="type === 'confirm'">
          <TextButton v-if="!noCancel" type="secondary" size="large" @click="cancelDrawer">{{
            cancelText || $t('APP.Common.Cancel.Text')
          }}</TextButton>
          <TextButton
            size="large"
            type="primary"
            :disabled="confirmDisabled"
            @disabled-click="emit('disabled-confirm')"
            @click="confirmDrawer"
            >{{ confirmText || $t('APP.Common.Confirm.Text') }}</TextButton
          >
        </block>
        <block v-else>
          <slot name="footer"></slot>
        </block>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import type { CSSProperties } from 'vue'
import TextButton from '@/common/textButton.vue'
import { useDismissInject } from '@/layout/page/constants'

const props = withDefaults(
  defineProps<{
    show: boolean
    placement: 'top' | 'bottom' | 'left' | 'right'
    alignment: 'left' | 'center'
    title?: string // 标题文本
    desc?: string // 描述文本
    width: string // 仅对 'left' | 'right' 生效
    height: string // 仅对 'top' | 'bottom' 生效
    drawerStyle?: CSSProperties
    maskStyle?: CSSProperties
    footerBordered?: boolean
    bottomOffset?: string
    /**
     * 弹框预设类型
     */
    type?: 'confirm'
    confirmText?: string // 确认按钮文本
    confirmDisabled?: boolean // 确认按钮禁用
    noCancel?: boolean // 是否隐藏取消按钮
    cancelText?: string // 取消按钮文本
    useCancelEvent?: boolean // 使用单独的取消按钮事件 代替 close事件
    innerHeight?: string
  }>(),
  {
    placement: 'bottom',
    alignment: 'left',
    width: 'auto',
    height: 'auto',
    footerBordered: true,
  }
)
const emit = defineEmits<{
  (e: 'update:show', show: boolean): void
  (e: 'close'): void
  (e: 'cancel'): void
  (e: 'confirm'): void
  (e: 'disabled-confirm'): void
}>()
const modalWrapperStyles = computed(() => {
  const styles: CSSProperties = {
    ...props.drawerStyle,
  }
  if (typeof props.bottomOffset === 'string') {
    // styles.transform = `translateY(-50%)`
    // styles.top = `calc(50% - ${props.bottomOffset})`
    styles.bottom = `${props.bottomOffset}`
  }
  if (props.innerHeight) {
    styles.height = props.innerHeight
  }

  return styles
})
function closeDrawer() {
  emit('update:show', false)
  emit('close')
}
function cancelDrawer() {
  emit('update:show', false)
  props.useCancelEvent ? emit('cancel') : emit('close')
}
function confirmDrawer() {
  emit('confirm')
  closeDrawer()
}

/**
 * 返回处理
 */
useDismissInject(() => props.show, closeDrawer)
</script>

<style scoped lang="less">
@import '@/styles/modal.less';
.drawer-header {
  color: var(--dark-color);
  padding: 48rpx 32rpx 22rpx;
  position: relative;
  .header-title {
    font-weight: 600;
    font-size: 40rpx;
    line-height: 56rpx;
    display: flex;
    align-items: center;
    &.align-left {
      justify-content: space-between;
    }
    &.align-center {
      justify-content: center;
    }
  }
  .close-btn {
    position: absolute;
    top: 40rpx;
    right: 24rpx;
    width: 60rpx;
    height: 60rpx;
    transform: translateX(8rpx);
    flex-shrink: 0;
    &.hovering {
      filter: brightness(0.8);
    }
    .close-icon {
      width: 100%;
      height: 100%;
    }
  }
}

.drawer-header,
.drawer-footer {
  flex-shrink: 0;
}
.drawer-body {
  flex: 1;
  overflow: auto;
  padding: 0 32rpx 56rpx;
}
.drawer.has-desc .drawer-body {
  padding-top: 16rpx;
}
.drawer-desc {
  font-weight: 400;
  font-size: 28rpx;
  line-height: 40rpx;
  color: rgba(var(--dark-vector), 0.6);
  margin-bottom: 16rpx;
}
.drawer-footer {
  padding: 32rpx;
  &.bordered {
    border-top: 2rpx solid #dadada;
  }
  &.is-button-group {
    padding: 32rpx 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    > text-button {
      flex: 1;
    }
  }
}
.drawer-bottom {
  bottom: 100rpx !important;
}
</style>
